<?php
namespace system\libraries\acl;

class Role
{
    /**
     * The role name
     * 
     * @var string
     */
    private $_name;
    
    /**
     * Role name to inherit from
     * 
     * @var string
     */
    private $_inherits;
    
    /**
     * Stores all resources for this role
     * 
     * @var array
     */
    private $_resources = array();
    
    /**
     * Constructor
     * 
     * @access public
     * @param string $name
     * @param string $inheritor
     */
    public function __construct( $name, $inherits )
    {
        $this->_name     = $name;
        $this->_inherits = $inherits;
    }
    
    /**
     * Get the role name this one inherits
     * 
     * @return string
     */
    public function getInherits()
    {
        return $this->_inherits;
    }
    
    /**
     * Magic method
     * 
     * @access public
     * @return string
     */
    public function __toString()
    {
        return $this->_name;
    }
    
    /**
     * Add a resource
     * 
     * @param mixed $controller
     * @param mixed $actions
     */
    public function addResource( $controller, $actions, $allowed = TRUE )
    {
        if ( ! is_array($actions) )
        {
            $actions = array($actions);
        }

        foreach ( $actions as $action )
        {
            $action = trim($action, '/');
            $parameters = explode('/', $action);
            
            // The resource contains parameters
            if ( count($parameters) > 1 )
            {
                // The first item is the action
                $action = $parameters[0];
                
                // Delete the action from the parameters array
                array_shift($parameters);
                
                if ( isset($this->_resources[$controller][$action]) )
                {
                    $this->_resources[$controller][$action] = NULL;
                }
                
                $this->_resources[$controller][$action][$parameters['0']] = $allowed;
            }
            else
            {
                $this->_resources[$controller][$action] = $allowed;
            }
        }
    }
    
    /**
     * Deny a resource
     * 
     * @param string $controller
     * @param mixed $actions
     */
    public function denyResource( $controller, $actions )
    {
        if ( ! is_array($actions) )
        {
            $actions = array($actions);
        }
        
        foreach ( $actions as $action )
        {
            $this->_resources[$controller][$action] = FALSE;
        }
    }
    
    /**
     * Checks if this role has a specific resource
     * 
     * @param string $controller
     * @param string $action
     * @return bool
     */
    public function hasResource( $controller, $action, $parameter )
    {        
        // The specific resource is valid!
        if ( $this->_hasResource($controller, $action, $parameter) === TRUE )
        {
            return TRUE;
        }

        // There is a global controller available, check this one too
        if ( isset($this->_resources[NULL]) )
        {
            // Just return it's result, we do not need to check further...
            return $this->_hasResource(NULL, $action, $parameter);
        }     
        
        // Well, the whole controller did not exist in the list, so yeah...
        return FALSE;
    }
    
    /**
     * Checks if the given resource is valid and is allowed for this role
     * 
     * @access private
     * @param string $controller
     * @param string $action
     * @param string $parameter
     * @return boolean 
     */
    private function _hasResource( $controller, $action, $parameter )
    {
        // There is an action
        if ( isset($this->_resources[$controller])
                && key_exists($action, $this->_resources[$controller]) )
        {
            // The action contains a parameter or parameters
            if ( is_array($this->_resources[$controller][$action]) )
            {
                if ( isset($this->_resources[$controller][$action][$parameter])
                        && $this->_resources[$controller][$action][$parameter] == TRUE )
                {
                    return TRUE;
                }
                return FALSE;
            }

            return (bool)$this->_resources[$controller][$action];
        }

        // All actions of this controller
        if ( isset($this->_resources[$controller][NULL]) )
        {
            return (bool)$this->_resources[$controller][NULL];
        }
    }
}

/* End of file Role.php */
